﻿using DbEntityTools.Model;
using System;
using System.Linq;
using System.Text;

namespace DbEntityTools.Service
{
    public class DbEntityCreateService
    {
        private static string indent = "    ";

        /// <summary>
        /// 创建实体类内容
        /// </summary>
        /// <param name="table"></param>
        /// <param name="namespaceStr"></param>
        /// <param name="isComAccress"></param>
        /// <returns></returns>
        public static string Create(TableModel table, string namespaceStr, bool isComAccress = false)
        {
            StringBuilder content = new StringBuilder();
            AddHeaders(content, table, namespaceStr, isComAccress);
            AddStructure(content, table, isComAccress);
            SetEntity(content, table, isComAccress);
            SetSelectSql(content, table, isComAccress);

            content.AppendLine(indent + "}");
            content.AppendLine("}");
            return content.ToString();
        }

        private static void AddHeaders(StringBuilder body, TableModel entity, string namespaceStr, bool isComAccress)
        { // 文件版权信息
            var copyright = DateTime.Now.Year + " xxxx Enterprises All Rights Reserved";
            var version = Environment.Version;
            var className = ToolHelper.ToHumpCase(entity.TableName);
            var author = "auto generated ";
            body.AppendLine("//-----------------------------------------------------------------------");
            body.AppendLine(string.Format("//<copyright file=\"{0}.cs\" >", className));
            body.AppendLine(string.Format("// * Copyright (C) {0}", copyright));
            body.AppendLine(string.Format("// * version : {0}", version));
            body.AppendLine(string.Format("// * author  : {0}", author));
            body.AppendLine(string.Format("// * FileName: {0}.cs", className));
            body.AppendLine(string.Format("// * history : Created by Auto {0} ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
            body.AppendLine("// </copyright>");
            body.AppendLine("//-----------------------------------------------------------------------");
            body.AppendLine("using System;");
            if (isComAccress)
            {
                body.AppendLine("using DataAccess.Attributes;");
                body.AppendLine("using DataAccess.Model;");
            }
            body.AppendLine("");
            body.AppendLine(string.Format("namespace {0}", namespaceStr));
            body.AppendLine("{");
        }

        private static void AddStructure(StringBuilder body, TableModel entity, bool isComAccress)
        {
            var indent2 = "       ";
            var indent3 = "            ";
            if (isComAccress)
            {
                body.AppendLine(indent2 + "/// <summary>");
                body.AppendLine(indent2 + "/// 查询sql");
                body.AppendLine(indent2 + "/// </summary>");
                body.AppendLine(indent2 + "public string GetSelectSql()");
                body.AppendLine(indent2 + "{");
                foreach (var item in entity.Fields)
                {
                    var defaultValue = GetDefaultValue(item);
                    if (defaultValue != null && defaultValue != "null")
                    {
                        body.AppendLine(indent3 + string.Format("this.{0} = {1};", item.Name, defaultValue));
                    }
                }
                body.AppendLine(indent2 + "}");
            }
        }

        private static void SetEntity(StringBuilder body, TableModel entity, bool isComAccress)
        {
            var entityDes = string.IsNullOrWhiteSpace(entity.TableDes) ? entity.TableName : entity.TableDes;
            body.AppendLine(indent + "/// <summary>");
            body.AppendLine(indent + string.Format("/// {0} Entity Model", entityDes));
            body.AppendLine(indent + "/// </summary>");
            if (isComAccress)
            {
                body.AppendLine(indent + string.Format("[Entity(\"{0}\")]", entity.TableName));
                body.AppendLine(indent + string.Format("[DataBase(\"{0}\")]", entity.DbName));
                body.AppendLine(indent + string.Format("public class {0} : BaseEntity<{0}>", ToolHelper.ToHumpCase(entity.TableName)));
            }
            else
            {
                body.AppendLine(indent + string.Format("public class {0}", ToolHelper.ToHumpCase(entity.TableName)));
            }
            body.AppendLine(indent + "{");
            foreach (var item in entity.Fields)
            {
                var s = SetField(item, isComAccress);
                body.AppendLine(s);
            }
        }

        /// <summary>
        /// 设置查询Sql
        /// </summary>
        /// <param name="body"></param>
        /// <param name="entity"></param>
        /// <param name="isComAccress"></param>
        private static void SetSelectSql(StringBuilder body, TableModel entity, bool isComAccress)
        {
            var indent2 = "       ";
            var indent3 = "            ";
            if (isComAccress)
            {
                body.AppendLine(indent2 + "/// <summary>");
                body.AppendLine(indent2 + "/// 查询sql");
                body.AppendLine(indent2 + "/// </summary>");
                body.AppendLine(indent2 + "public override string GetSelectSql()");
                body.AppendLine(indent2 + "{");
                var fields = entity.Fields.Select(x => x.Name);
                body.AppendLine(indent3 + string.Format("return \"SELECT {0} FROM {1} WHERE 1=1\";", string.Join(",", fields), entity.TableName));
                body.AppendLine(indent2 + "}");
            }
        }

        private static string SetField(FieldModel field, bool isComAccress)
        {
            var indent = "       ";
            StringBuilder result = new StringBuilder();
            result.AppendLine(indent + "/// <summary>");
            result.AppendLine(indent + string.Format("/// {0}", field.Comment));
            result.AppendLine(indent + "/// </summary>");
            if (isComAccress)
            {
                if (field.IsPrimaryKey)
                {
                    result.AppendLine(indent + string.Format("[PrimaryKey({0})]", field.IsIdentity ? "true" : "false"));
                }
                result.AppendLine(indent + string.Format("[DBField(FieldName = \"{0}\")]", field.Name));
                result.AppendLine(indent + string.Format("public {0} {1} ", field.Type, ToolHelper.ToHumpCase(field.Name)) + "{ get; set; }");
            }
            else
            {
                result.AppendLine(indent + string.Format("public {0} {1} ", field.Type, field.Name) + "{ get; set; }");
            }
            return result.ToString();
        }

        private static string GetDefaultValue(FieldModel fieldModel)
        {
            var value = fieldModel.DefaultValue;
            if (fieldModel.Type == "DateTime" && string.IsNullOrWhiteSpace(fieldModel.DefaultValue) == false)
            {
                value = string.Format("DateTime.Parse(\"{0}\")", fieldModel.DefaultValue);
            }
            if (string.IsNullOrWhiteSpace(value) && fieldModel.Type == "string")
            {
                value = "string.Empty";
            }
            return value;
        }
    }
}
